package edu.ssm.campusAssistant.utils;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import com.fasterxml.jackson.databind.node.ObjectNode;
import edu.ssm.campusAssistant.utils.bo.JumpBO;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 标题:初始化加载功能配置信息
 * 描述:
 *
 * @autho LXF
 * @date 2019/4/7 20:31
 */
@Service
public class JumpUtils {
    /**
     * 功能对应的map
     */
    public static Map<String, JumpBO> jumpMap = new HashMap<String, JumpBO>();
    private static final ObjectMapper mapper = new ObjectMapper();

    @PostConstruct
    public static void init() throws JsonParseException, JsonMappingException, IOException {
        BufferedReader reader = null;
        String laststr = "";
        try {
            FileInputStream fileInputStream = new FileInputStream(JumpUtils.class.getClassLoader().getResource("init.json").getFile());
            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
            reader = new BufferedReader(inputStreamReader);
            String tempString = null;
            while ((tempString = reader.readLine()) != null) {
                laststr += tempString;
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        StringBuilder argBuffer = new StringBuilder();
        jsonFormat(mapper.readTree(laststr), argBuffer, 0, false);
        List<?> object = mapper.readValue(argBuffer.toString(), List.class);

        List<JumpBO> lst = mapper.readValue(mapper.writeValueAsString(object), mapper.getTypeFactory().constructCollectionType(List.class, JumpBO.class));
        for (JumpBO jumpBO : lst) {
            System.out.println(jumpBO.toString());
            jumpMap.put(jumpBO.getService(), jumpBO);
        }

    }

    private static void jsonFormat(JsonNode node, StringBuilder json, int deep, boolean underScore) {
        JsonNodeType nt = node.getNodeType();
        if (nt == JsonNodeType.ARRAY) {
            ArrayNode an = (ArrayNode) node;
            json.append("[");
            Iterator<JsonNode> elements = an.elements();
            ++deep;
            while (elements.hasNext()) {
                jsonFormat(elements.next(), json, deep, underScore);
                if (elements.hasNext()) {
                    json.append(",");
                }
            }
            --deep;
            json.append("]");
        } else if (nt == JsonNodeType.OBJECT) {
            ObjectNode on = (ObjectNode) node;
            Iterator<Map.Entry<String, JsonNode>> fields = on.fields();
            json.append("{");
            ++deep;
            while (fields.hasNext()) {
                json.append("\n");
                for (int i = 0; i < deep; i++) {
                    json.append("        ");
                }
                Map.Entry<String, JsonNode> field = fields.next();

                json.append("\"").append(underScore ? underscoreName(field.getKey()) : camelCaseName(field.getKey())).append("\":");
                jsonFormat(field.getValue(), json, deep, underScore);
                if (fields.hasNext()) {
                    json.append(",");
                }
            }
            --deep;
            json.append("\n");
            for (int i = 0; i < deep; i++) {
                json.append("        ");
            }
            json.append("}");
        } else if (nt == JsonNodeType.STRING) {
            json.append("\"").append(node.asText()).append("\"");
        } else if (nt == JsonNodeType.NULL) {
            json.append(node.asText());
        } else if (nt == JsonNodeType.BOOLEAN) {
            json.append(node.asText());
        } else if (nt == JsonNodeType.NUMBER) {
            json.append(node.asText());
        } else {
            // nusupported
        }
    }

    /**
     * 转换为驼峰（大写）
     *
     * @param underscoreName
     * @return
     */
    public static String camelCaseName(String underscoreName) {
        StringBuilder result = new StringBuilder();
        if (underscoreName != null && underscoreName.length() > 0) {
            boolean flag = false;
            for (int i = 0; i < underscoreName.length(); i++) {
                char ch = underscoreName.charAt(i);
                if ("_".charAt(0) == ch) {
                    flag = true;
                } else {
                    if (flag) {
                        result.append(Character.toUpperCase(ch));
                        flag = false;
                    } else {
                        result.append(Character.toLowerCase(ch));
                    }
                }
            }
        }
        return result.toString();
    }

    /**
     * 转换为下划线(大写)
     *
     * @param camelCaseName
     * @return
     */
    public static String underscoreName(String camelCaseName) {
        StringBuilder result = new StringBuilder();
        int len = camelCaseName.length();
        if (camelCaseName != null && len > 0) {
            result.append(camelCaseName.substring(0, 1).toUpperCase());
            for (int i = 1; i < len; i++) {
                char ch = camelCaseName.charAt(i);
                if (Character.isUpperCase(ch)) {
                    result.append("_");
                    result.append(ch);
                } else {
                    result.append(Character.toUpperCase(ch));
                }
            }
        }
        return result.toString();
    }
}
